from apps.user import verify_token

# from blueprint.user import verify_token as app_verify_token
from flask import current_app
from utilsapp.mysql_con import db_connect
import datetime
from dateutil.relativedelta import relativedelta
import arrow
import inspect
import jwt
import platform
import hashlib
import uuid, os, sys
import psutil

filename = inspect.getframeinfo(inspect.currentframe()).filename
this_dir = os.path.dirname(os.path.abspath(filename))


# 获取近年的年月
def get_one():
    ret = []
    today = arrow.now()
    for i in range(0, 12):
        last_month = today.shift(months=-i).format("YYYY-MM")
        ret.append(str(last_month))
    return ret


# 通过递归将字典列表转为tree结构
def list_to_tree(
    index, dict_list, sub_field="children", pid_field="pid", id_field="value"
):
    sub = []
    for x in dict_list:
        if x[pid_field] == index:
            x[sub_field] = list_to_tree(x[id_field], dict_list)
            sub.append(x)
    return sub


def build_tree(data, parent_id=None):
    tree = []
    for item in data:
        if item["pid"] == parent_id:
            node = {
                "value": item["value"],
                "label": item["label"],
                "type": item["type"],
                "pid": item["pid"],
                "proj_no": item["proj_no"],
                "factory_img": item["factory_img"],
                "x_per": item["x_per"],
                "y_per": item["y_per"],
                "mergerName": item["mergerName"],
                "children": build_tree(data, parent_id=item["value"]),
            }
            tree.append(node)
    return tree


def build_tree1(data, p):
    p["children"] = []
    if p["type"] == "zone":
        return p
    for item in data:
        if item["pid"] == p["value"]:
            p["children"].append(build_tree1(data, item))
    return p


# 解析用户的数据权限
def parsing_permissions(request):
    headers = request.headers
    url = request.path
    token = headers["Authorization"]
    if (
        "Android" in headers["User-Agent"]
        or "iPhone" in headers["User-Agent"]
        or "Mobile" in headers["User-Agent"]
    ):
        source = 0
    else:
        source = 1
    flag = verify_token(token, current_app.config["settings"]["SECRET_KEY"], source)[
        "flag"
    ]

    sql = f"select type from regionlevel where id ={flag['dataId']}"
    res = db_connect(sql)
    if not res["data"]:
        return {"dataId": 0, "type": "admin", "warnpermission": 1}
    else:
        type_ = db_connect(sql)["data"][0]["type"]
        warnpermission = flag["warnpermission"]
        return {
            "dataId": flag["dataId"],
            "type": type_,
            "warnpermission": warnpermission,
        }


def get_time_arr(now_t_str, dots, freqs):
    T = 1 / freqs
    now_t = datetime.datetime.strptime(now_t_str, "%Y-%m-%d %H:%M:%S")
    return [str(now_t + datetime.timedelta(seconds=T * item)) for item in range(dots)]


def ok(
    data="",
    msg: str = "请求成功",
):
    return {"code": 0, "msg": msg, "data": data}


def fail(msg: str = "请求失败", data=None, err: Exception = None):
    return {"code": -1, "msg": msg, "data": data, "error": str(err) if err else ""}


def str_to_date(str_date, fomat="%Y-%m-%d %H:%M:%S"):
    return datetime.datetime.strptime(str_date, fomat)


def str_to_date_disparity(str_date, num, format="%Y-%m-%d %H:%M:%S"):
    date_obj = datetime.datetime.strptime(str_date, format)
    previous_month = date_obj - relativedelta(months=num)
    return previous_month


def date_to_str(dateobj, fomat="%Y-%m-%d %H:%M:%S"):
    return dateobj.strftime(fomat)


# 解析 dataId
def parsing_data_id(scope_id, request):
    if scope_id is None:
        scope_id = 0
    if scope_id != 0:
        scope_sql = f"""SELECT type FROM regionlevel where id = {scope_id} """
        type_ = db_connect(scope_sql)["data"][0]["type"]
        return f"{type_}_id={scope_id}"
    else:

        scope_id = parsing_permissions(request)["dataId"]

        type_ = parsing_permissions(request)["type"]
        if scope_id != 0:
            return f"{type_}_id={scope_id}"
        else:
            return ""


def get_url_user(request):

    token = (
        ""
        if "Authorization" not in request.headers
        else request.headers["Authorization"]
    )
    key = current_app.config["settings"]["SECRET_KEY"]
    user_name = ""
    try:
        info = jwt.decode(token, key, algorithms="HS256")
        user_name = info["user_name"]
    except:
        pass
    return user_name


def find_str(s, sub):
    """
    使用find方法查找子字符串
    """
    if s.find(sub) != -1:
        return True
    else:
        return False


def assign_value(dictionary, key, default_=""):
    try:
        if dictionary[key] is None:
            return default_
        else:
            return dictionary[key]
    except KeyError:
        return default_


def create_code(short_name, exp_time, win_code):
    payload = {"exp": exp_time, "short_name": short_name, "win_code": win_code}
    return jwt.encode(payload=payload, key=win_code[1:-2], algorithm="HS256")


def check_code(token):
    try:
        return True, None

    except Exception as e:
        print("授权已失效,请将机器码复制后，联系厂商重新授权")
        return False, None

def get_process_using_port(port):
    for conn in psutil.net_connections(kind="inet"):
        if conn.laddr.port == port:
            return psutil.Process(conn.pid)
    return None


def dilute_list(lst, a):
    if len(lst) > a:
        ratio = len(lst) / a
        new_lst = [lst[int(i * ratio)] for i in range(a)]
        return new_lst
    else:
        return lst


def get_operate(request):
    headers = request.headers

    token = headers["Authorization"]
    key = current_app.config["settings"]["SECRET_KEY"]
    info = jwt.decode(token, key, algorithms="HS256")

    return info


def get_collection(mgdb, query, projection, dbname, limit_flag="", limit=1):
    # 选择数据库和集合
    collection = mgdb[dbname]
    try:
        query_result = collection.find(query, projection)
        if limit_flag == "limit1":
            query_result = query_result.sort([("_id", -1)]).limit(limit)
        result_list = list(query_result)
        if not result_list:
            raise ValueError("No data found in the collection.")
        return result_list
    except Exception as e:
        collection = mgdb["eige"]
        query_result = collection.find(query, projection)
        if limit_flag == "limit1":
            query_result = query_result.sort([("_id", -1)]).limit(limit)
        result_list = list(query_result)
        return result_list


def get_collection_name(mgdb, dbname, redis=None):
     
    if  redis is None:
        
        redis = current_app.redis
    try:
         
        key = redis.hget(f"eige_dblist", f"{dbname}")
      
        if key:
            return dbname
      
        else:
            collections = mgdb.list_collection_names()
            for collection in collections:
                redis.hset("eige_dblist", f"{collection}", 1)
            redis.expire("eige_dblist", 60 * 10)
            if dbname in collections:
                return dbname
            else:
                return "eige"
        
    except Exception as e:
        print("err get_collection_name",str(e))
        return "eige"
